<template>
  <form class="cmp cmp-hide">
    <fieldset>
      <legend>参数设置</legend>
      <div class="fieldset-content">
        <div class="form-group form-item-row" align="center">
          <div class="form-item-label">主文件</div>
          <div class="form-item-input"><input class="form-control" type="text" v-model="mainFilePath" placeholder="请选择主文件" readonly /></div>
          <div class="form-item-suffix"><x-button @click="setMainFilePath">选择...</x-button></div>
        </div>
        <div class="form-group form-item-row" align="center">
          <div class="form-item-label">隐藏文件</div>
          <div class="form-item-input"><input class="form-control" type="text" v-model="hideFilePath" placeholder="请选择要隐藏的文件" readonly /></div>
          <div class="form-item-suffix"><x-button @click="setHideFilePath">选择...</x-button></div>
        </div>
        <div class="form-group form-item-row" align="center">
          <div class="form-item-label">导出位置</div>
          <div class="form-item-input"><input class="form-control" type="text" v-model="saveFilePath" placeholder="请选择文件处理后的存储位置" readonly /></div>
          <div class="form-item-suffix"><x-button @click="setSaveFilePath">选择...</x-button></div>
        </div>
        <div class="form-group form-item-row" align="center" v-if="targetFilePath">
          <div class="form-item-label">导出文件</div>
          <div class="form-item-input text-grey">{{targetFilePath}}</div>
        </div>
        <div class="form-group form-group-main"></div>
        <div class="form-group form-item-row" align="center">
          <x-button type="primary" block @click="encrypt" :loading="loadingCount > 0">开始处理</x-button>
        </div>
      </div>
    </fieldset>
  </form>
</template>

<script>
const fs = global.require('fs')
const path = global.require('path')
const {remote} = global.require('electron')
const {dialog} = remote
const selfWindow= remote.getCurrentWindow()
const readFile = (filePath) => {
  return new Promise((resolve, reject) => {
    fs.readFile(filePath, (err, data) => {
      if (!err && data) {resolve(data)}
      else {reject('读取文件失败')}
    })
  })
}

export default {
  name: 'hide',
  data () {
    return {
      mainFilePath: '',
      hideFilePath: '',
      saveFilePath: this.$sharedObject('desktopPath'),
      targetFilePath: '',
      loadingCount: 0,
    }
  },
  methods: {
    // 选择主文件
    setMainFilePath () {
      let filePaths = dialog.showOpenDialogSync(selfWindow, {
        title: '选择文件',
        buttonLabel:'确定',
        defaultPath: this.$sharedObject('desktopPath'),
        properties: ['openFile']
      })
      if (filePaths instanceof Array && filePaths.length > 0) {
        this.mainFilePath = filePaths[0]
      }
    },
    // 选择隐藏文件
    setHideFilePath () {
      let filePaths = dialog.showOpenDialogSync(selfWindow, {
        title: '选择文件',
        buttonLabel:'确定',
        defaultPath: this.$sharedObject('desktopPath'),
        properties: ['openFile']
      })
      if (filePaths instanceof Array && filePaths.length > 0) {
        this.hideFilePath = filePaths[0]
      }
    },
    // 设置加密文件保存位置
    setSaveFilePath () {
      let filePaths = dialog.showOpenDialogSync(selfWindow, {
        title: '选择目录',
        buttonLabel:'确定',
        defaultPath: this.$sharedObject('desktopPath'),
        properties: ['openDirectory']
      })
      if (filePaths instanceof Array && filePaths.length > 0) {
        this.saveFilePath = filePaths[0]
      }
    },
    // 表单校验
    checkForm () {
      let result = true
      if (!this.mainFilePath) {
        result = false
        this.$toast('主文件不能为空')
      }
      if (!this.hideFilePath) {
        result = false
        this.$toast('隐藏文件不能为空')
      }
      return result
    },
    // 加密
    encrypt () {
      if (!this.checkForm()) return
      this.loadingCount++
      this.targetFilePath = ''
      Promise.all([
        readFile(this.mainFilePath),
        readFile(this.hideFilePath),
      ]).then(([mainFile, hideFile]) => {
        if (!mainFile) { return this.$toast('主文件加载失败') }
        if (!hideFile) { return this.$toast('隐藏文件加载失败') }
        let mainFileData = new Uint8Array(mainFile)
        let hideFileData = new Uint8Array(hideFile)
        let mainFileExt = path.extname(this.mainFilePath) || ''
        let hideFileExt = (path.extname(this.hideFilePath) || '').substring(1, 5)
        let sepData = new TextEncoder().encode(`-sep-${hideFileExt.padEnd(4, ' ')}`)
        let targetData = new Uint8Array(mainFileData.length + sepData.length + hideFileData.length)
        let targetFilePath = path.join(this.saveFilePath, `hide_${Date.now()}${mainFileExt}`)
        targetData.set(mainFileData, 0)
        targetData.set(sepData, mainFileData.length)
        targetData.set(hideFileData, mainFileData.length + sepData.length)
        this.loadingCount++
        this.$sharedObject('jstoolsNode').writeFile(targetFilePath, Buffer.from(targetData)).then(() => {
          this.$toast('导出完成')
          this.targetFilePath = targetFilePath
        }).catch((err) => {
          this.$toast('导出错误：' + err)
        }).finally(() => {
          this.loadingCount--
        })
      }).finally(() => {
        this.loadingCount--
      })
    },
  }
}
</script>

<style scoped lang="less">
@import "~@/assets/css/_mixins.less";
@import "~@/assets/css/_color.less";
.form-item-row {
  display: flex;
  .form-item-label {
    min-width: 4em;
    margin-right: .5em;
    text-align-last: justify;
  }
  .form-item-input {
    width: 0;
    flex-grow: 1;
    text-align: left;
  }
  .form-item-suffix {
    margin-left: .5em;
    min-width: 2em;
  }
  &[align="center"] {
    align-items: center;
  }
}
.cmp-hide {
  height: 100%;
  fieldset {
    height: 100%;
    .fieldset-content {
      height: calc(100% - 2em);
      display: flex;
      flex-direction: column;
      .form-group-main {
        height: 0;
        flex-grow: 1;
      }
    }
  }
}
</style>
